package com.jd.rapid.rpc.client;

import com.jd.rapid.rpc.client.proxy.RpcAsyncProxy;
import com.jd.rapid.rpc.client.proxy.RpcProxyImpl;

import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class RpcClient {

    private String serverAddress;

    private long timeout;

    private final Map<Class<?>,Object> syncProxyInstanceMap=new ConcurrentHashMap<>();

    private final Map<Class<?>,Object> asyncProxyInstanceMap=new ConcurrentHashMap<>();


    public void initClient(String serverAddress,long timeout){
        this.serverAddress=serverAddress;
        this.timeout=timeout;
        connect();
    }

    private void connect() {
        //交给rpcConnectManger
        RpcConnectManager.getInstance().connect(serverAddress);
    }

    public void stop(){
        //交给rpcConnectManger
        RpcConnectManager.getInstance().stop();
    }


    /**
     * 同步调用方法
     * 生成代理对象
     * @param interfaceClass
     * @param <T>
     * @return
     */
    public <T> T invokeSync(Class<T> interfaceClass){
        if(syncProxyInstanceMap.containsKey(interfaceClass)){
            return (T) syncProxyInstanceMap.get(interfaceClass);
        }else {
            Object proxy = Proxy.newProxyInstance(interfaceClass.getClassLoader(),
                    new Class<?>[]{interfaceClass},
                    new RpcProxyImpl(interfaceClass, timeout)
            );
            syncProxyInstanceMap.put(interfaceClass, proxy);
            return (T) proxy;
        }
    }


    /**
     * 异步调用方法
     * @param interfaceClass
     * @param <T>
     * @return
     */
    public <T> RpcAsyncProxy invokeAsync(Class<T> interfaceClass){
        if(asyncProxyInstanceMap.containsKey(interfaceClass)){
            return (RpcAsyncProxy) asyncProxyInstanceMap.get(interfaceClass);
        }else {
            RpcProxyImpl<T> asyncProxyInstance = new RpcProxyImpl(interfaceClass, timeout);
            asyncProxyInstanceMap.put(interfaceClass,asyncProxyInstance);
            return asyncProxyInstance;
        }
    }
}
